package xu.jiang.report.dealer.layer;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import xu.jiang.report.Param;
import xu.jiang.report.R;
import xu.jiang.report.dealer.report.MyReportDealer;
import xu.jiang.report.dealer.ISQLRunner;
import xu.jiang.report.util.DataHelper;
import xu.jiang.report.util.SQLUtil;
import xu.jiang.report.util.report.POIUtil;
import xu.jiang.report.util.report.RegexUtil;
import xu.jiang.report.util.report.ReportUtil;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;

/**
 * 循环层 必定不包含合并单元格
 * 
 * @author jx
 */
public class LoopLayer extends AbstractIndexLayer<MySQLData> {

	private final LayerBaseParam layerBaseParam;

	private final  MySQLDataCollector mySQLDataCollector;


	public LoopLayer(LayerBaseParam layerBaseParam)  {
		super(layerBaseParam.index, layerBaseParam.param);
		this.layerBaseParam = layerBaseParam;
		this.mySQLDataCollector = new MySQLDataCollector(layerBaseParam);
	}

	@Override
	public MySQLData collectData(ISQLRunner sqlRunner, Map<String, String> pagingParamValues) throws IOException {

		return this.mySQLDataCollector.collectData(sqlRunner,pagingParamValues);
	}

	@Override
	public int writeData(int appendRowNum, Sheet sheet,MySQLData data) {

		/*
		 * 计算当前数据写入的行号
		 */
		int currentIndexRow = appendRowNum + this.getIndex();
		/*
		 * 插入空白行 注意startRowIndex也是数据行，故空白行应该少插一行
		 */
		int size = 	data.pureData.size();
		if (data.pureData == null || size <= 0) {// 虽然数据没有，但是该层的替换符的位置依然属于本层

			return 0;
		}

		if (size >= 2 ) {
			POIUtil.insertRowsAfterRowIndex(sheet, currentIndexRow, size - 1, false);
		}


		this.writeDataByStartRowIndex(currentIndexRow,sheet,data);

		//由于层内属性的替换符所在行也会被数据填充，所以需要【减 1】
		return size - 1;


	}
	protected int writeDataByStartRowIndex(int currentIndexRow, Sheet sheet, MySQLData data) {

		return this.writeDataByStartRowIndex(currentIndexRow,sheet,data,0,data.pureData.size()-1);
	}

	/**
	 *
	 * @param currentIndexRow
	 * @param sheet
	 * @param data
	 * @return 下一行
	 */
	protected int writeDataByStartRowIndex(int currentIndexRow, Sheet sheet, MySQLData data,int printDataStart,int printDataEnd) {
		List<Object[]> olist = data.pureData;
		boolean appendRowNo = data.appendRowNo;
		/*
		 * 将值放入单元格
		 */
		// 找到复制的样式
		CellStyle rowStyle = null;
		//行高
		Short rowHeight = 20;
		// 遍历行
		for (int i = printDataStart; i <= printDataEnd; i++, currentIndexRow++) {

			// 初次获取row值
			Object[] initialArr = olist.get(i);
			// 真正的row
			List<Object> r = new LinkedList<>();
			// 是否需要在行首加入行号
			if (appendRowNo) {
				r.add(String.valueOf(i + 1));
			}
			r.addAll(Arrays.asList(initialArr));

			Row row = POIUtil.getOrCreateRow(sheet, currentIndexRow);

			//设计行样式
			if(i==printDataStart) {
				rowStyle = row.getRowStyle();
				rowHeight = row.getHeight();

			}else {
				row.setRowStyle(rowStyle);
				row.setHeight(rowHeight);
			}

			int colNum = r.size() ;
			for (int j = 0; j < colNum; j++) {// 遍历行内单元格,
				Cell c = POIUtil.getOrCreateCell(row, j);

				//设置单元格的值
				String v = this.filterValue(r.get(j));
				if (StringUtils.isNotEmpty(v)) {
					c.setCellValue(v);
				}

				//设置单元格样式
//				if (j > 0 && i > 0) {
				if (i > printDataStart) {
					//获取上一行的行样式
					Row upRow = POIUtil.getOrCreateRow(sheet, currentIndexRow - 1);

					CellStyle previousStyle = POIUtil.getOrCreateCell(upRow, j).getCellStyle();

					c.setCellStyle(previousStyle);

				}

			}
			// 层的第一行数据无需选择合并，因为模板已经合并了
			if (i > 0) {
				// 必须在创建行之前合并
				this.addMergingCells4Layer(sheet, currentIndexRow);
			}

		}
		return currentIndexRow;
	}


	/**
	 * 为层插入合并单元格 必须在数据填充层之前
	 * 
	 * @param sheet
	 * @param currentIndexRow
	 */
	protected void addMergingCells4Layer(Sheet sheet, int currentIndexRow) {
		/*
		 * 行内数据写入完毕，开始处理合并单元格的情况
		 */
		if (this.layerBaseParam.mergingColumns == null || this.layerBaseParam.mergingColumns.size() <= 0) {
			return;
		}
		/*
		 * 循环层的变化仅是行号的变化，列号没变
		 */
		for (CellRangeAddress perRange : this.layerBaseParam.mergingColumns) {
			/*
			 * 合并单元格的高度
			 */
			int rangRowHeight = perRange.getLastRow() - perRange.getFirstRow();

			int firstRow = currentIndexRow;
			int lastRow = currentIndexRow + rangRowHeight;
			int firstCol = perRange.getFirstColumn();
			int lastCol = perRange.getLastColumn();
			CellRangeAddress newR = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);

			sheet.addMergedRegion(newR);
		}
	}

	/**
	 * 对数据库中的值进行过滤美化
	 * 
	 * @param v
	 * @return
	 */
	protected String filterValue(Object v) {
		if (v == null || StringUtils.isBlank(v.toString())) {
			return "";
		}

		if (v instanceof Integer) {
			double d = (Integer) v;
			if (d == 0) {
				return "0";
			}
			return String.valueOf(d);

		} else if (v instanceof Double) {// 保留三位精度
			double d = (Double) v;
			if (d == 0) {
				return "0";
			}
			return String.valueOf(DataHelper.formatDouble(Double.valueOf(d)));

		} else if (v instanceof BigDecimal) {
			BigDecimal b = (BigDecimal) v;
			double d = b.doubleValue();
			if (d == 0) {
				return "0";
			}
			return String.valueOf(DataHelper.formatDouble(Double.valueOf(d)));

		} else if (v instanceof Date) {
			Date date = (Date) v;
			return new SimpleDateFormat("yyyy/MM/dd").format(date);
		}

		return String.valueOf(v);
	}

	/**
	 * 清空上一页缓存，便于下一页使用 为了处理不同分页使用同一结构时，出现缓存的现象
	 */
	@Override
	public void clear() {
		this.mySQLDataCollector.clear();
	}


}
